/************************************************************************/
// Copyright (C) 2016, han_gangbiao. All rights reserved.
// Use of this source code is governed by a GPL-v2 license that can be found in the License file.
// 
// [Time]:      2016-3-18 21:06:32
// [Author]:    han_gangbiao [http://my.oschina.net/jackhen]
// [Info]:      
/************************************************************************/

#ifndef INCLUDE_RPC_SERVER_BASE_H_
#define INCLUDE_RPC_SERVER_BASE_H_

#include "base/xrefptr.h"
#include "base/xmutex.h"
#include "base/xguard.h"
#include "base/xthread.h"
#include "net/net_reactor.h"
#include "protocol/net_binary_decoder.h"
#include "protocol/net_proto_def.h"
#include <map>


class CRpcServerMgr;

class RpcBean : public smart::refobj_t
{
public:
    RpcBean( SOCK_FD fd, const char* ip, int port, IBinaryDecoderListener* decoder_listener );
    ~RpcBean();
public:
    SOCK_FD m_fd;
    char m_ip[64];
    int m_port;
    NetBinaryDecoder m_decoder;
};

class RpcBeanMap
{
public:
    RpcBeanMap( CRpcServerMgr* pMgr );
    ~RpcBeanMap();
    
    smart::ref_ptr<RpcBean> get_rpc_bean(SOCK_FD fd);
    int add_rpc_bean(RpcBean* bean);
    int del_rpc_bean(SOCK_FD fd);
    void del_all_rpc_bean();
    
    int close_rpc_bean(SOCK_FD fd);
    void close_all_rpc_bean();
private:
    smart::mutex_t m_lock;
    std::map< SOCK_FD, smart::ref_ptr<RpcBean> > m_beans;
    CRpcServerMgr* m_pMgr;
};


class CRpcServerBase : public IBinaryDecoderListener, public smart::refobj_t
{
    friend class CRpcServerMgr;
public:
    CRpcServerBase( CRpcServerMgr* pMgr );
protected: //should not to delete
    virtual ~CRpcServerBase();

public:
    int start_rpc_server( const char* local_ip, int local_port );
    int stop_rpc_server();
public:
    int invoke( SOCK_FD fd, const smart::ref_ptr<NetBinaryPdu>& pdu );
protected:
    virtual int on_invoke( SOCK_FD fd, smart::ref_ptr<NetBinaryPdu> pdu ) = 0;
    virtual int on_rpc_close( SOCK_FD fd, int errcode ) = 0;

protected:
    RpcBeanMap m_rpc_bean_map;
private:
    int on_connect( SOCK_FD cli_fd, const char* remote_ip, int remote_port );
	int on_data( SOCK_FD fd, const char* data, int len, const char* remote_ip, int remote_port );
	int on_send_ack( SOCK_FD fd, int len );
	int on_close( SOCK_FD fd, int error );
    int on_listen_close( SOCK_FD listenfd, int error );
    virtual int onPDU( int fd, smart::ref_ptr<NetBinaryPdu> pdu );
	virtual int onError( int fd, BinaryDecoderError_t err );
private:
    CRpcServerMgr* m_pMgr;
    SOCK_FD m_listenfd;
};


#endif //~INCLUDE_RPC_SERVER_BASE_H_

